home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / source / units / tokens.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1993-12-10  |  9.9 KB  |  320 lines

  1. UNIT Tokens;
  2.  
  3. INTERFACE
  4.  
  5. CONST     Tnil=0; { The batch is empty }
  6.           Tpre=1; { Number prefix, #$%& }
  7.  
  8.           Tdel=2; { Collection of delimiters, SPACE TAB NL CR }
  9.           Twrd=3; { Collection of letters, A-Z a-z Æ¥Å æ¢å    }
  10.           Tnum=4; { Collection of numbers, if not prefixed    }
  11.                   { ($#%&), then it is assumed decimal (#).   }
  12.           Tunk=5; { Unknown token, only one character returns }
  13.  
  14. VAR       Translated:BOOLEAN;
  15.  
  16. FUNCTION  FrontStrip(S:STRING):STRING;
  17. FUNCTION  Strip(S:STRING):STRING;
  18. FUNCTION  NumToByte(Num:STRING):BYTE;
  19. FUNCTION  NumToWord(Num:STRING):WORD;
  20. FUNCTION  Roll(VAR S:STRING):CHAR;
  21. FUNCTION  IsHex(Chr:CHAR):BOOLEAN;
  22. FUNCTION  IsBin(Chr:CHAR):BOOLEAN;
  23. FUNCTION  IsOct(Chr:CHAR):BOOLEAN;
  24. FUNCTION  Len(S:STRING):BYTE; 
  25. PROCEDURE LowerCase(VAR Str:STRING);
  26. PROCEDURE UpperCase(VAR Str:STRING);
  27. FUNCTION  WhatChar(C:CHAR):BYTE;
  28.  
  29. PROCEDURE NextToken(VAR Batch,Token:STRING; VAR WhatToken:BYTE);
  30.  
  31. PROCEDURE OpenTokenFile(VAR Fil:TEXT; VAR A,B,C,D:STRING; VAR E:BYTE; VAR F:WORD);
  32. PROCEDURE NextFileToken(VAR Fil:TEXT; VAR A,B,C:STRING; VAR D:BYTE; VAR E:WORD);
  33. PROCEDURE NextFileChar(VAR Fil:TEXT; VAR A,B,C:STRING; VAR D:BYTE; VAR E:WORD);
  34. PROCEDURE SkipFileString(VAR Fil:TEXT; VAR A,B,C:STRING; VAR D:BYTE; VAR E:WORD);
  35. PROCEDURE CloseTokenFile(VAR Fil:TEXT);
  36.  
  37. IMPLEMENTATION
  38.  
  39. FUNCTION  FrontStrip(S:STRING):STRING;
  40.  BEGIN
  41.    WHILE (S[1]=' ') DO S:=COPY(S,2,Len(S)-1); FrontStrip:=S;
  42.  END;
  43.  
  44. FUNCTION  Strip(S:STRING):STRING;
  45.  BEGIN
  46.    WHILE S[Len(S)]=' ' DO S:=COPY(S,1,Len(S)-1); Strip:=S;
  47.  END;
  48.  
  49. FUNCTION  NumToByte(Num:STRING):BYTE;
  50.  VAR T:BYTE; Meth:CHAR; Res:WORD;
  51.  BEGIN
  52.     Meth:=Roll(Num); NumToByte:=0; Translated:=FALSE;
  53.     IF (Meth='$') AND (Len(Num)>2) THEN Exit; { $FF       }
  54.     IF (Meth='#') AND (Len(Num)>3) THEN Exit; { #255      }
  55.     IF (Meth='&') AND (Len(Num)>4) THEN Exit; { &377      }
  56.     IF (Meth='%') AND (Len(Num)>8) THEN Exit; { %11111111 }
  57.     Translated:=TRUE; UpperCase(Num); Res:=0;
  58.     FOR T:=1 TO Len(Num) DO
  59.      BEGIN
  60.        IF Meth='%' THEN Res:=Res*2+(ORD(Num[T])-48);
  61.        IF Meth='&' THEN Res:=Res*8+(ORD(Num[T])-48);
  62.        IF Meth='#' THEN Res:=Res*10+(ORD(Num[T])-48);
  63.        IF Meth='$' THEN IF Num[T]<='9' THEN Res:=Res*16+(ORD(Num[T])-48)
  64.                                        ELSE Res:=Res*16+(ORD(Num[T])-55);
  65.      END;
  66.     NumToByte:=Res;
  67.  END;
  68.  
  69. FUNCTION  NumToWord(Num:STRING):WORD;
  70.  VAR T:BYTE; Meth:CHAR; Res:WORD;
  71.  BEGIN
  72.     Meth:=Roll(Num); NumToWord:=0; Translated:=FALSE;
  73.     IF (Meth='$') AND (Len(Num)>4)  THEN Exit; { $FFFF             }
  74.     IF (Meth='#') AND (Len(Num)>5)  THEN Exit; { #65535            }
  75.     IF (Meth='&') AND (Len(Num)>6)  THEN Exit; { &177777           }
  76.     IF (Meth='%') AND (Len(Num)>16) THEN Exit; { %1111111111111111 }
  77.     Translated:=TRUE; UpperCase(Num); Res:=0;
  78.     FOR T:=1 TO Len(Num) DO
  79.      BEGIN
  80.        IF Meth='%' THEN Res:=Res*2+(ORD(Num[T])-48);
  81.        IF Meth='&' THEN Res:=Res*8+(ORD(Num[T])-48);
  82.        IF Meth='#' THEN Res:=Res*10+(ORD(Num[T])-48);
  83.        IF Meth='$' THEN IF Num[T]<='9' THEN Res:=Res*16+(ORD(Num[T])-48)
  84.                                        ELSE Res:=Res*16+(ORD(Num[T])-55);
  85.      END;
  86.     NumToWord:=Res;
  87.  END;
  88.  
  89. FUNCTION  Roll(VAR S:STRING):CHAR; ASSEMBLER;
  90.  ASM
  91.      PUSH DS            { Save DS }
  92.      LDS  SI,S          { Get adress of string }
  93.      MOV  AL,DS:[SI]    { Get string length }
  94.      CMP  AL,0          { Exit if lenght of string is zero }
  95.      JE   @Qt
  96.      MOV  CH,AL         { Copy string length for shuffling }
  97.      DEC  AL            { Decrease string length with one }
  98.      MOV  DS:[SI],AL    { Stuff the length back into the specifier }
  99.      INC  SI            { Prepare to shuffle letters one back }
  100.      MOV  DH,DS:[SI]    { Get character to be returned }
  101. @lp: MOV  AL,DS:[SI+1]  { Get next character }
  102.      MOV  DS:[SI],AL    { Shuffle it back in }
  103.      INC  SI            { Jump to next character }
  104.      DEC  CH            { Mark character as shuffeled }
  105.      CMP  CH,0          { Is there more characters to shuffle? }
  106.      JG   @lp           { Yes, do the loop again. }
  107.      MOV  AL,DH         { Return character shuffled out earlier }
  108. @Qt: POP  DS            { Restore DS }
  109.  END;
  110.  
  111. FUNCTION  IsHex(Chr:CHAR):BOOLEAN; ASSEMBLER;
  112.  ASM
  113.      MOV  AL,Chr
  114.      MOV  AH,FALSE
  115.      CMP  AL,048; JL  @Qt {0}
  116.      CMP  AL,057; JLE @Ok {9}
  117.      CMP  AL,065; JL  @Qt {A}
  118.      CMP  AL,070; JLE @Ok {F}
  119.      CMP  AL,097; JL  @Qt {a}
  120.      CMP  AL,102; JG  @Qt {f}
  121. @Ok: MOV  AH,TRUE
  122. @Qt: MOV  AL,AH
  123.  END;
  124.  
  125. FUNCTION  IsBin(Chr:CHAR):BOOLEAN; ASSEMBLER;
  126.  ASM
  127.      MOV  AL,Chr
  128.      MOV  AH,FALSE
  129.      CMP  AL,048; JL  @Qt {0}
  130.      CMP  AL,049; JG  @Qt {1}
  131. @Ok: MOV  AH,TRUE
  132. @Qt: MOV  AL,AH
  133.  END;
  134.  
  135. FUNCTION  IsOct(Chr:CHAR):BOOLEAN; ASSEMBLER;
  136.  ASM
  137.      MOV  AL,Chr
  138.      MOV  AH,FALSE
  139.      CMP  AL,048; JL  @Qt {0}
  140.      CMP  AL,055; JG  @Qt {7}
  141. @Ok: MOV  AH,TRUE
  142. @Qt: MOV  AL,AH
  143.  END;
  144.  
  145. FUNCTION  Len(S:STRING):BYTE; ASSEMBLER;
  146.  ASM
  147.      LES  SI,S
  148.      MOV  AL,ES:[SI]
  149.  END;
  150.  
  151. PROCEDURE LowerCase(VAR Str:STRING); ASSEMBLER;
  152.  ASM
  153.      LES  DI,Str
  154.      MOV  CL,ES:[DI]
  155.      INC  DI
  156. @n0: MOV  AL,ES:[DI]
  157.      CMP  AL,'Å'; JNE @n1; MOV  AL,'å'
  158. @n1: CMP  AL,'¥'; JNE @n2; MOV  AL,'¢'
  159. @n2: CMP  AL,'Æ'; JNE @n3; MOV  AL,'æ'
  160. @n3: CMP  AL,'A'; JL  @n4
  161.      CMP  AL,'Z'; JG  @n4
  162.      XOR  AL,32
  163. @n4: STOSB
  164.      DEC CL
  165.      CMP CL,0
  166.      JGE @n0
  167.  END;
  168.  
  169. PROCEDURE UpperCase(VAR Str:STRING); ASSEMBLER;
  170.  ASM
  171.      LES  DI,Str
  172.      MOV  CL,ES:[DI]
  173.      INC  DI
  174. @n0: MOV  AL,ES:[DI]
  175.      CMP  AL,'å'; JNE @n1; MOV  AL,'Å'
  176. @n1: CMP  AL,'¢'; JNE @n2; MOV  AL,'¥'
  177. @n2: CMP  AL,'æ'; JNE @n3; MOV  AL,'Æ'
  178. @n3: CMP  AL,'a'; JL  @n4
  179.      CMP  AL,'z'; JG  @n4
  180.      XOR  AL,32
  181. @n4: STOSB
  182.      DEC CL
  183.      CMP CL,0
  184.      JGE @n0
  185.  END;
  186.  
  187. FUNCTION  WhatChar(C:CHAR):BYTE; ASSEMBLER;
  188.  ASM
  189.      MOV  AH,C
  190.      MOV  AL,Tdel         { Delimiters }
  191.      CMP  AH,032; JE  @Qt
  192.      CMP  AH,010; JE  @Qt
  193.      CMP  AH,013; JE  @Qt
  194.      CMP  AH,009; JE  @Qt
  195.      MOV  AL,Tnum          { Numbers }
  196.      CMP  AH,048; JL  @Nx
  197.      CMP  AH,057; JLE @Qt
  198. @Nx: MOV  AL,Twrd          { Letters }
  199.      CMP  AH,065; JL  @Ny
  200.      CMP  AH,090; JLE @Qt
  201.      CMP  AH,097; JL  @Ny
  202.      CMP  AH,122; JLE @Qt
  203.      CMP  AH,134; JE  @Qt
  204.      CMP  AH,143; JE  @Qt
  205.      CMP  AH,145; JE  @Qt
  206.      CMP  AH,146; JE  @Qt
  207.      CMP  AH,155; JE  @Qt
  208.      CMP  AH,157; JE  @Qt
  209. @Ny: MOV  AL,Tpre          { Prefix }
  210.      CMP  AH,035; JL  @Nz
  211.      CMP  AH,038; JLE @Qt
  212. @Nz: MOV  AL,Tunk          { Unknown }
  213. @Qt:
  214.  END;
  215.  
  216. {╔══════════════════════════════════════════════════════════════════════════╗
  217.  ║ Handles one line at the time                                             ║
  218.  ╚══════════════════════════════════════════════════════════════════════════╝}
  219.  
  220. PROCEDURE NextToken(VAR Batch,Token:STRING; VAR WhatToken:BYTE);
  221.  BEGIN
  222.    Token:=''; WhatToken:=Tnil; IF Len(Batch)=0 THEN Exit;
  223.    IF WhatChar(Batch[1])=Tunk THEN
  224.     BEGIN
  225.       WhatToken:=Tunk; Token:=Roll(Batch); Exit;
  226.     END;
  227.    IF WhatChar(Batch[1])=Twrd THEN
  228.     BEGIN
  229.       WhatToken:=Twrd;
  230.       WHILE (WhatChar(Batch[1])=Twrd) AND (Len(Batch)>0)
  231.          DO Token:=Token+Roll(Batch); Exit;
  232.     END;
  233.    IF WhatChar(Batch[1])=Tnum THEN
  234.     BEGIN
  235.       WhatToken:=Tnum; Token:='#';
  236.       WHILE (WhatChar(Batch[1])=Tnum) AND (Len(Batch)>0)
  237.          DO Token:=Token+Roll(Batch); Exit;
  238.     END;
  239.    IF (WhatChar(Batch[1])=Tpre) AND (Batch[1]='#') THEN
  240.     BEGIN
  241.       WhatToken:=Tnum; Token:=Roll(Batch);
  242.       WHILE (WhatChar(Batch[1])=Tnum) AND (Len(Batch)>0)
  243.          DO Token:=Token+Roll(Batch); Exit;
  244.     END;
  245.    IF (WhatChar(Batch[1])=Tpre) AND (Batch[1]='$') THEN
  246.     BEGIN
  247.       WhatToken:=Tnum; Token:=Roll(Batch);
  248.       WHILE (IsHex(Batch[1])) AND (Len(Batch)>0)
  249.          DO Token:=Token+Roll(Batch); Exit;
  250.     END;
  251.    IF (WhatChar(Batch[1])=Tpre) AND (Batch[1]='%') THEN
  252.     BEGIN
  253.       WhatToken:=Tnum; Token:=Roll(Batch);
  254.       WHILE (IsBin(Batch[1])) AND (Len(Batch)>0)
  255.          DO Token:=Token+Roll(Batch); Exit;
  256.     END;
  257.    IF (WhatChar(Batch[1])=Tpre) AND (Batch[1]='&') THEN
  258.     BEGIN
  259.       WhatToken:=Tnum; Token:=Roll(Batch);
  260.       WHILE (IsOct(Batch[1])) AND (Len(Batch)>0)
  261.          DO Token:=Token+Roll(Batch); Exit;
  262.     END;
  263.    IF WhatChar(Batch[1])=Tdel THEN
  264.     BEGIN
  265.       WhatToken:=Tdel;
  266.       WHILE (WhatChar(Batch[1])=Tdel) AND (Len(Batch)>0)
  267.          DO Token:=Token+Roll(Batch); Exit;
  268.     END;
  269.  END;
  270.  
  271. {╔══════════════════════════════════════════════════════════════════════════╗
  272.  ║ "Advanced" file-token handling                                           ║
  273.  ╚══════════════════════════════════════════════════════════════════════════╝}
  274.  
  275. PROCEDURE OpenTokenFile(VAR Fil:TEXT; VAR A,B,C,D:STRING; VAR E:BYTE; VAR F:WORD);
  276.  BEGIN                 { tokenfile , name , batch , token , origin, result , line }
  277.     ASSIGN(Fil,A); RESET(Fil); READLN(Fil,B);
  278.     C:=''; D:=B; E:=Tnil; F:=1;
  279.  END;
  280.  
  281. PROCEDURE NextFileToken(VAR Fil:TEXT; VAR A,B,C:STRING; VAR D:BYTE; VAR E:WORD);
  282.  BEGIN                 { tokenfile , batch , token , origin , result , line }
  283.    NextToken(A,B,D);
  284.    IF EOF(Fil) AND (D=Tnil) THEN
  285.     BEGIN
  286.       B:=''; A:=''; D:=Tnil; Exit;
  287.     END ELSE
  288.    IF D=Tnil THEN
  289.     BEGIN
  290.       READLN(Fil,A); INC(E); C:=A;
  291.       B:=#10+#13; D:=Tdel;
  292.     END;
  293.  END;
  294.  
  295. PROCEDURE NextFileChar(VAR Fil:TEXT; VAR A,B,C:STRING; VAR D:BYTE; VAR E:WORD);
  296.  BEGIN                { tokenfile , batch , token, origin , result , line }
  297.    IF EOF(Fil) AND (Len(A)=0) THEN
  298.     BEGIN
  299.       B:=''; D:=Tnil; A:=''; Exit;
  300.     END ELSE
  301.    IF Len(A)=0 THEN
  302.     BEGIN
  303.       READLN(Fil,A); INC(E); C:=A;
  304.     END;
  305.    B:=Roll(A);
  306.    D:=WhatChar(B[1]);
  307.  END;
  308.  
  309. PROCEDURE SkipFileString(VAR Fil:TEXT; VAR A,B,C:STRING; VAR D:BYTE; VAR E:WORD);
  310.  BEGIN                  { tokenfile, batch , token , origin , result , line }
  311.    READLN(Fil,A); B:=#10+#13; C:=A; D:=Tdel; INC(E);
  312.  END;
  313.  
  314. PROCEDURE CloseTokenFile(VAR Fil:TEXT);
  315.  BEGIN
  316.    CLOSE(Fil);
  317.  END;
  318.  
  319. BEGIN
  320. END.